home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
LIBRARY
/
VTOOLS
/
VTWIN.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1995-03-13
|
16KB
|
425 lines
UNIT VTWIN;
INTERFACE
Uses VTFAST;
Const MaxWindows = 20; { Maximal used Windows }
MaxScreens = 5; { Maximal screens to save }
UserScreens : Byte = 5; { User defined screens
Get Memory for UserScreens ->
UserScreens * VideoPage Bytes }
UserWindows : Byte = 10;
WinStackPt : Byte = 0;
StartMemorySize : LongInt = 0;
AttachedWindows : set of byte = [];
Type WinHook = Procedure;
Type WinStack = Array[1..MaxWindows] of Byte; { Here save a window ID No. }
Type ScreenDescription = RECORD
ScreenBuffer : Pointer;
CursorX,
CursorY,
CursorT,
CursorB : Byte;
Saved,
Allocated : Boolean;
END;
Type WindowDescription = RECORD {This is description }
WinX,WinY,
WinX1,WinY1,
BoxT : Byte; { of any of a window }
Explode,
ShadowFlag : Boolean;
Title : String[78];
TitleF,TitleB : Byte;
BoxF,BoxB : Byte;
InnerF,InnerB : Byte;
SavedScreen : Pointer;
CalledProcedure : WinHook; { When user display }
Attached, { window this proce- }
Displayed : Boolean; { dure is calling. }
END; { WARNING!
PROCEDURE MUST BE IN
A FAR MODEL }
Type Direction = (Left,Right,Up,Down);
Var W_Array : Array[1..MaxWindows] of ^WindowDescription;
S_Array : Array[1..MaxScreens] Of ^ScreenDescription;
Stack : WinStack;
Procedure WinInit; { Initialize unit with startup parameters. Not recomended
to use it with defined windows }
Procedure RemoveAllMemory; { Good for a end }
{ of program }
Procedure SaveScreen(Num : Byte);
Procedure RestoreScreen(Num : Byte);
Procedure AllocateScreens; { To use a save&restore}
Procedure DisposeScreens; { screen must Allocate it first}
Procedure GetFromScreen(X,Y,X1,Y1 : Word; Dest : Pointer); {Grabs & Puts }
Procedure PutToScreen(X,Y,X1,Y1 : Word; Source : Pointer); {blocks from screen}
{Source must be a reserved before memory block
with length ((X1-X) * 2) + ((Y1-Y)*160) Bytes }
Procedure CopyScreenBlock(X,Y,X1,Y1,NewX,NewY : Word); { Copies block from
Screen to another coordinates
!!! WARNING: MUST !!! NewX < X AND NewX > X1 }
Procedure Scroll(X,Y,X1,Y1,Attr : Byte;Ch : Char;Dir : Direction);
Procedure DisplayShadow(X,Y,X1,Y1 : Byte);
Procedure DefineWindow(Winnum,X,Y,X1,Y1,Box : Byte;Expl,Shadow : Boolean;Tit : String);
Procedure SetWindowColors(WinNum,BoxFor,BoxBack,TitF,TitB,InF,InB : Byte);
Procedure AssignWinProc (WinNum : Byte;PassedProc : WinHook);
Procedure AllocateWindows; {Reserve memory for UserWindows. !MUST BE USED }
Procedure DisposeWindows; {Reliease memory} {FOR USING DISPLAY WINDOW}
Procedure DisplayWindow(WinNum : byte);
Procedure RemoveWindow; {Remove the last displayed window}
Procedure TempMessage(X,Y,TxtF,TxtB : Byte;Txt : String);
Procedure TempMessageChar(X,Y,TxtF,TxtB : Byte;Txt : String;Var Ch : Char);
Procedure TempMessageBox(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB : Byte;Txt : String);
Procedure TempMessageBoxChar(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB : Byte;Txt : String;Var Ch : Char);
{
Procedure ExplodeTempMessageBox(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB : Byte;Txt : String);
Procedure ExplodeTempMessageBoxChar(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB : Byte;
Txt : String;Var Ch : Char);
}
IMPLEMENTATION
Const SavedMemoryFlag : Boolean = False;
Var Tmp : Byte;
StartMemoPoint : Pointer;
CalledHook : Pointer;
{$L VTWIN}
{$F+}
Procedure GetScreen(Dest : Pointer); EXTERNAL;
Procedure PutScreen(Source : Pointer); EXTERNAL;
Procedure GetFromScreen(X,Y,X1,Y1 : Word; Dest : Pointer); EXTERNAL;
Procedure PutToScreen(X,Y,X1,Y1 : Word; Source : Pointer); EXTERNAL;
Procedure CopyScreenBlock(X,Y,X1,Y1,NewX,NewY : Word); EXTERNAL;
{$F-}
Procedure VTWinERROR(Status : Byte);
Var Msg : String[70];
Begin
Write('VTWIN Error #',Status);
Case Status Of
1 : Msg :='. Screen/Window must be alocated first!';
2 : Msg :='. Unable to create more Screens/Windows. Request is more than maximal.';
3 : Msg :='. Unable to allocate memory for operation!';
4 : Msg :='. Window allready displayed!.';
5 : Msg :='. Too many open windows!';
6 : Msg :='. Screen not saved! Can`t activate.';
End;
WriteLn(Msg);
RemoveAllMemory;
Halt;
End;
Procedure RemoveAllMemory;
Begin
If SavedMemoryFlag Then Dispose(StartMemoPoint);
End;
Procedure AllocateScreens;
Begin
For Tmp := 1 To UserScreens Do Begin
If Tmp > MaxScreens Then VTWinError(2);
If MaxAvail < (SizeOf(ScreenDescription)+VPageL) Then VTWinError(3);
GetMem(S_Array[Tmp],SizeOf(ScreenDescription));
GetMem(S_Array[Tmp]^.ScreenBuffer,VPageL);
S_Array[Tmp]^.Allocated := true;
End;
End;
Procedure DisposeScreens;
Begin
For Tmp := 1 To UserScreens Do If S_Array[Tmp]^.Allocated Then
Begin
S_Array[Tmp]^.Allocated := False;
FreeMem(S_Array[Tmp]^.ScreenBuffer,VPageL);
FreeMem(S_Array[Tmp],SizeOf(ScreenDescription));
End;
End;
{===========* Same like VTKEY.GETKEY *================}
procedure Getkey(var AscCode,PosCode : Byte); assembler;
asm
PUSH DS { Save the DS & ES }
PUSH ES
MOV AH,0h { Attach the 0 function | Get next key or wait for key }
INT 16h
LES DI,AscCode { Load the ASCII code }
STOSB
MOV AL,AH { Load Position code }
LES DI,PosCode
STOSB
POP ES { Restore old ES & DS }
POP DS
end;
Procedure SaveScreen(Num : Byte);
Begin
If Not S_Array[Num]^.Allocated Then VTWinError(1);
With S_Array[Num]^ Do Begin
GetXY(CursorX,CursorY);
GetCursor(CursorT,CursorB);
GetScreen(ScreenBuffer);
Saved := True;
End;
End;
Procedure RestoreScreen(Num : Byte);
Begin
If Not S_Array[Num]^.Allocated Then VTWinError(1);
If Not S_Array[Num]^.Saved Then VTWinError(6);
With S_Array[Num]^ Do Begin
XY(CursorX,CursorY);
SetCursor(CursorT,CursorB);
PutScreen(ScreenBuffer);
End;
End;
Procedure Scroll(X,Y,X1,Y1,Attr : Byte;Ch : Char;Dir : Direction);
Var BlockSize : Word;
Pt : Pointer;
Begin
Case Dir of
Up : Begin
ScrollUp(X,Y,X1,Y1,1,Attr);
PlainWrite(X,Y1,ReplicateChar(X1-X+1,ch));
End;
Down : Begin
ScrollDown(X,Y,X1,Y1,1,Attr);
PlainWrite(X,Y,ReplicateChar(X1-X+1,ch));
End;
Left :Begin
CopyScreenBlock(X+1,Y,X1,Y1,X,Y);
ColorWriteVert(X1,Y,Attr,0,ReplicateChar(Y1-Y+1,ch));
End;
Right :Begin
BlockSize := ((X1-X-1) shl 2) + ((Y1-Y)*160);
If MaxAvail < BlockSize Then VTWinError(3);
GetMem(pt,BlockSize);
GetFromScreen(X,Y,X1-1,Y1,pt);
PutToScreen(X+1,Y,X1,Y1,Pt);
FreeMem(pt,BlockSize);
ColorWriteVert(X,Y,Attr,0,ReplicateChar(Y1-Y+1,ch));
End;
End;
End;
Procedure PushWindow(WinNum : Byte);
Begin
Inc(WinStackPt);
If WinStackPt > MaxWindows Then VTWinError(5);
Stack[WinStackPt] := WinNum;
End;
Procedure PopWindow;
Begin
If WinStackPt < 1 Then Exit;
Dec(WinStackPt);
End;
Function PushedWindow : Byte;
Begin
If WinStackPt < 1 Then PushedWindow := 0;
PushedWindow := Stack[WinStackPt];
End;
Procedure DisposeWindows;
Begin
For Tmp := 1 TO MaxWindows Do FreeMem(W_Array[Tmp],Sizeof(WindowDescription));
End;
Procedure DefineWindow(WinNum,X,Y,X1,Y1,Box : Byte;Expl,Shadow : Boolean;Tit : String);
Begin
With W_Array[WinNum]^ do Begin
WinX := X;
WinY := Y;
WinX1 := X1;
WinY1 := Y1;
BoxT := Box;
Explode := Expl;
ShadowFlag := Shadow;
If (WinX < 3) OR (WinY1 > 23) Then ShadowFlag := False;
Title := Tit;
End;
AttachedWindows := AttachedWindows + [WinNum];
End;
Procedure SetWindowColors(WinNum,BoxFor,BoxBack,TitF,TitB,InF,InB : Byte);
Begin
With W_Array[WinNum]^ Do Begin
BoxF := BoxFor;
BoxB := BoxBack;
TitleF := TitF;
TitleB := TitB;
InnerF := InF;
InnerB := InB;
End;
End;
Procedure AssignWinProc ( WinNum : Byte;PassedProc : WinHook);
Begin
W_Array[WinNum]^.CalledProcedure := PassedProc;
End;
Procedure AllocateWindows;
Var WinBlock : Word;
Begin
If UserWindows > MaxWindows Then VTWinError(3);
For Tmp := 1 to UserWindows do IF Tmp in AttachedWindows Then
With W_Array[Tmp]^ Do
Begin
IF ShadowFlag Then WinBlock := ((WinX1-WinX+2) shl 1) + ((WinY1-WinY+1) * 160)
Else WinBlock := ((WinX1-WinX) shl 1) + ((WinY1-WinY) * 160);
If MaxAvail < WinBlock Then VTWinError(3);
GetMem(SavedScreen,WinBlock);
Attached := True;
End;
End;
Procedure DisplayShadow(X,Y,X1,Y1 : Byte);
Var
Fore,Back : Word;
Procedure SetShadow(Xp,Yp : Byte); { INTERNAL }
Begin
GetCharAttributes(Xp,Yp,Fore,Back);
If Fore > 8 Then Fore := Fore - 8
Else Fore := 8;
If Back > 8 Then Back := Back - 8
Else Back := 0;
SetCharAttr(Xp,Yp,Attrib(Fore,Back));
End;
Begin
For Tmp := X-2 To X1-2 Do Begin
SetShadow(Tmp,Y1+1);
End;
For Tmp := Y+1 To Y1 Do Begin
SetShadow(X-1,Tmp);
SetShadow(X-2,Tmp);
End;
End;
Procedure DisplayWindow(WinNum : byte);
Begin
With W_Array[WinNum]^ Do
Begin
If Not Attached Then VTWinError(1);
If Displayed Then VTWinError(4);
{============ HERE MUST DISABLE PREVIOUS WINDOW =============}
Displayed := True;
PushWindow(WinNum);
If ShadowFlag Then GetFromScreen(WinX-2,WinY,WinX1,WinY1+1,SavedScreen)
Else GetFromScreen(WinX,WinY,WinX1,WinY1,SavedScreen);
If Explode Then ExplodeBox(WinX,WinY,WinX1,WinY1,BoxF,BoxB,BoxT)
Else Begin
ClearText(WinX,WinY,WinX1,WinY1,BoxF,BoxB);
DrawBox(WinX,WinY,WinX1,WinY1,BoxT);
End;
ClearText(WinX+1,WinY+1,WinX1-1,WinY1-1,InnerF,InnerB);
ColorWriteBetween(WinX,WinX1,WinY,TitleF,TitleB,Title);
If ShadowFlag Then DisplayShadow(WinX,WinY,WinX1,WinY1); {++ HERE PUSH SHADOW ++}
If Addr(CalledProcedure) <> Nil Then CalledProcedure;
End;
End;
Procedure RemoveWindow;
Begin
Tmp := PushedWindow;
With W_Array[Tmp]^ Do Begin
PopWindow;
Displayed := False;
If ShadowFlag Then PutToScreen(WinX-2,WinY,WinX1,WinY1+1,SavedScreen)
Else PutToScreen(WinX,WinY,WinX1,WinY1,SavedScreen);
{===== HERE MUST ENABLE PREVIOUS WINDOW =====}
End;
End;
Procedure TempMessage(X,Y,TxtF,TxtB : Byte;Txt : String);
Var Ch : Char;
Begin
TempMessageChar(X,Y,TxtF,TxtB,Txt,Ch);
End;
Procedure TempMessageChar(X,Y,TxtF,TxtB : Byte;Txt : String;Var Ch : Char);
Var Pt : Pointer;
A,B : Byte;
Begin
If X = 0 Then X := 39 - (Length(Txt) div 2);
If Y = 0 Then Y := 12;
If MaxAvail < (Length(txt) shl 1) Then VTWinError (3);
GetMem(Pt,Length(txt) shl 1);
GetFromScreen(X,Y,x+Length(Txt),Y,pt);
ColorWrite(X,Y,TxtF,TxtB,Txt);
GetKey(a,b);
PutToScreen(X,Y,x+Length(Txt),Y,pt);
FreeMem(Pt,Length(txt) shl 1);
Ch := Chr(a);
End;
Procedure TempMessageBox(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB : Byte;Txt : String);
Var ch : Char;
Begin
TempMessageBoxChar(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB,Txt,Ch);
End;
Procedure TempMessageBoxChar(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB : Byte;Txt : String;Var Ch : Char);
Var Pts : Pointer;
BlockSizeC : Word;
A,B : Byte;
AVM : Word;
Begin
If X < 2 Then X := 38 - (Length(Txt) div 2);
If Y < 2 Then Y := 12;
BlockSizeC := (Length(Txt) Shl 1) + 480;
AvM := MaxAvail;
If AvM< BlockSizeC Then VTWinError(3);
GetMem(pts,BlockSizeC);
GetFromScreen(X-1,Y-1,X+Length(Txt)+1,Y+1,PtS);
ClearText(X-1,Y-1,X+Length(Txt)+1,Y+1,BoxF,BoxB);
DrawBox(X-1,Y-1,X+Length(Txt)+1,Y+1,Boxt);
ColorWrite(X,Y,TxtF,TxtB,Txt);
GetKey(A,B);
PutToScreen(X-1,Y-1,X+Length(Txt)+1,Y+1,PtS);
FreeMem(pts,BlockSizeC);
Ch := Chr(A);
End;
{ ***** WORKING BUT NO USED NOW, BECOUSE IS LIKE TempMessageBox **********
Procedure ExplodeTempMessageBox(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB : Byte;Txt : String);
Var Ch : Char;
Begin
ExplodeTempMessageBoxChar(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB,Txt,Ch);
End;
Procedure ExplodeTempMessageBoxChar(X,Y,BoxF,BoxB,BoxT,TxtF,TxtB : Byte;
Txt : String;Var Ch : Char);
Var Pt : Pointer;
BlockSize : Word;
Begin
If X < 2 Then X := 38 - (Length(Txt) div 2);
If Y < 2 Then Y := 12;
BlockSize := (Length(Txt) Shl 1) + 480;
If MaxAvail < BlockSize Then VTWinError(3);
GetMem(pt,BlockSize);
GetFromScreen(X-1,Y-1,X+Length(Txt)+1,Y+1,Pt);
ExplodeBox(X-1,Y-1,X+Length(Txt)+1,Y+1,BoxF,BoxB,BoxT);
ColorWrite(X,Y,TxtF,TxtB,Txt);
GetKey(Key,Key1);
PutToScreen(X-1,Y-1,X+Length(Txt)+1,Y+1,Pt);
FreeMem(pt,BlockSize);
Ch := Chr(Key);
End; ------------}
Procedure WinInit;
Begin
StartMemorySize := MaxAvail;
For Tmp := 1 To MaxScreens Do Begin
GetMem(S_Array[Tmp],SizeOf(ScreenDescription));
S_Array[Tmp]^.Saved := False;
S_Array[Tmp]^.Allocated := False;
End;
For Tmp := 1 To MaxWindows do Begin
GetMem(W_Array[Tmp],SizeOf(WindowDescription));
With W_Array[Tmp]^ Do Begin
Displayed := False;
Attached := False;
CalledProcedure := Nil;
Title := '';
End;
End;
attachedWindows :=[];
If Not SavedMemoryFlag Then Begin
Mark(StartMemoPoint);
Release(StartMemoPoint);
Mark(StartMemoPoint);
End;
End;
BEGIN
WinInit;
END.